using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Storage;
using System.IO;
using Microsoft.Xna.Framework.GamerServices;

namespace Tetrazune
{
    public enum DataStates
    {
        Free,
        PreparingDevice,
        Reading,
        Writing
    }

    public class HighScoreManager
    {
        const int MaxScores = 10;
        HighScore[] myScores = new HighScore[MaxScores];
        HighScore[] friendScores = new HighScore[MaxScores];
        DataStates state = DataStates.Free;
        IAsyncResult result;

        public HighScoreManager(bool loadScores)
        {
            if (loadScores)
                LoadAll();
        }

        public bool IsInHighScores(int score, bool useLocalScores)
        {
            return InsertLocation(score,
                (useLocalScores ? myScores : friendScores)) >= 0;
        }

        public int AddHighScore(HighScore score, bool useLocalScores)
        {
            HighScore[] scr =(useLocalScores ? myScores : friendScores);
            int index = InsertLocation(score.Score, scr);
            if (index < 0) return -1;
            for (int i = MaxScores - 1; i > index; i--)
                scr[i] = scr[i - 1];
            scr[index] = score;
            return index;
        }

        private int InsertLocation(int score, HighScore[] scores)
        {
            for (int i = 0; i < scores.Length; i++)
                if (score > scores[i].Score)
                    return i;
            return -1;
        }

        public void Update()
        {
            if (result != null && result.IsCompleted)
            {
                FileAccess mode = (FileAccess)result.AsyncState;
                StorageDevice dev = Guide.EndShowStorageDeviceSelector(result);
                if (!dev.IsConnected) return;
                if (mode == FileAccess.Read)
                    Save(dev);
                else
                    Load(dev);
                result = null;
            }
        }

        public DataStates State
        {
            get { return state; }
        }

        public void LoadAll()
        {
            if (state != DataStates.Free || Guide.IsVisible)
                throw new ApplicationException("Cannot Load data at this time.");
            state = DataStates.PreparingDevice;
            result = Guide.BeginShowStorageDeviceSelector(null, FileAccess.Read);
        }

        public void SaveAll()
        {
            if (state != DataStates.Free || Guide.IsVisible)
                throw new ApplicationException("Cannot Save data at this time.");
            state = DataStates.PreparingDevice;
            result = Guide.BeginShowStorageDeviceSelector(null, FileAccess.Write);
        }

        private void Save(StorageDevice device)
        {
            StorageContainer con = device.OpenContainer("TetraZune");
            string file = Path.Combine(con.Path, "scores.sav");
            String localDat = "";
            String friendDat = "";
            for (int i = 0; i < MaxScores; i++)
            {
                localDat += HighScore.Serialize(myScores[i]).Replace('\n', ' ') + "\n";
                friendDat += HighScore.Serialize(friendScores[i]).Replace('\n', ' ') + "\n";
            }
            state = DataStates.Writing;
            FileStream fs = new FileStream(file, FileMode.OpenOrCreate);
            StreamWriter sw = new StreamWriter(fs);
            sw.Write(localDat + '\n' + friendDat);
            sw.Close();
            state = DataStates.Free;
        }

        private void Load(StorageDevice device)
        {
            StorageContainer con = device.OpenContainer("TetraZune");
            string file = Path.Combine(con.Path, "scores.sav");
            state = DataStates.Reading;
            FileStream fs = new FileStream(file, FileMode.Open);
            StreamReader sr = new StreamReader(fs);
            String data = sr.ReadToEnd();
            sr.Close();
            String[] myData = data.Substring(0, data.IndexOf("\n\n") + 1).Split('\n');
            String[] friendData = data.Substring(myData.Length + 1).Split('\n');
            for (int i = 0; i < MaxScores; i++)
            {
                myScores[i] = HighScore.Deserialize(myData[i]);
                friendScores[i] = HighScore.Deserialize(friendData[i]);
            }
            state = DataStates.Free;
        }

    }
}